basicmicrofandomcom-20200214-history
MBasic: Compiler Preprocessor
In most cases the operation of the compiler is automatic and transparent: you simply write your program and click the Program button. However, the Atom BASIC compiler includes a "preprocessor" that accepts instructions ("directives") to control compiling according to rules you specify. The preprocessor has two basic functions: #It lets you keep a collection of frequently used program modules ("snippets" of code) and include them whenever you need them. #It provides conditional tests (IF ... THEN) to modify the code you compile, allowing you to use the same basic code to compile different versions of a program. Including Files Perhaps you’ve written a subroutine to control an LCD display, and you’d like to use this subroutine in various different programs. You can save the subroutine on disk, and "include" it whenever you need it. #include The #include directive is used to "paste" program modules at compile time. Modules are pasted at the location of the #include directive. Syntax :#include "filename" :#include "partial or complete path to file" Example Assume that your LCD subroutine called "lcd.bas" and is in the same directory as your main program. The subroutine contains the label "displaywrite". You can include this in your program like this: :main :(some code) ::gosub displaywrite :(some more code) :#include "lcd.bas" :end The #include directive simply pastes in the code from lcd.bas as if it was part of your program. If lcd.bas is in a subdirectory of your program directory, just put the partial path, for example: :#include "modules\lcd.bas" If it’s in another directory, you can include the relative or absolute path, using normal Windows notation. Conditional Compiling Sometimes the same program may be used for slightly different applications. For example, if you’ve written a program to display temperature from a sensor, you may want versions for Celsius and Fahrenheit degrees, or perhaps you want one version to use an LCD display and a different one to output serial data to your computer. Most of the code is identical, but some constants, variables and subroutines may differ. Conditional compiling lets you set a "switch" in your program (usually a constant, but not necessarily) that controls compiling. You can have different constants, variables, or even different sections of code compiled depending on the switch or switches that you set. #IF ... #ENDIF Similar to the usual BASIC if ... then conditional branch. Specifies code to be compiled if the expression is true. Syntax :#IF constant expression Example :fahr con 1 :#IF fahr=1 :... some code ... :#ENDIF :... rest of program ... This will compile the code between #if and #endif only if fahr=1. If fahr has any other value, the code between #if and #endif will be skipped. #IFDEF ... #ENDIF Compiles the following code (up to #ENDIF) only if the constant or variable is defined, or if the label appears previously in the code. Syntax :#IFDEF name ; name is a variable, constant or label Example 1 :temperature var byte :#IFDEF temperature :... some code ... :#ENDIF :... rest of program ... This will compile "some code" because "temperature" has been defined. Example 2 :main :... some code ... :#IFDEF main :... conditional code ... :#ENDIF :... rest of program ... This will compile "conditional code" because the label "main" precedes the #IFDEF condition. #IFNDEF ... #ENDIF Compiles the code between #IFNDEF and #ENDIF only if the constant or variable has not been defined, or the label has not been previously used in the program. In effect, it’s the inverse of #IFDEF. #ELSE Allows you to have two code snippets, and compile one or the other depending on the result of the #IF, #IFDEF or #IFNDEF directive. Syntax :#ELSE Example :fahr con 1 :#IF fahr=1 :... some code ... :#ELSE :... some other code ... :#ENDIF :... rest of program ... Compiles "some code" if fahr = 1 and "some other code" if fahr has any other value. #ELSEIF Allows multiple snippets of code to be compiled based on multiple tests. Regard this as an extension of the #ELSE directive. Syntax :#ELSEIF constant expression Example :screentype con 1 :#IF screentype=1 :... some code ... :#ELSEIF screentype=2 :... some other code ... :#ELSEIF screentype=3 :... yet more code ... :#ENDIF :... rest of program ... Compiles "some code", "some other code", or "yet more code" respectively when screentype is 1, 2 or 3. If screentype has some other value, compilation simply continues with "rest of program" and none of the snippets is compiled. #ELSEIFDEF, #ELSEIFNDEF Equivalents of #ELSEIF for the #IFDEF and #IFNDEF directives. Syntax :#ELSEIFDEF name :#ELSEIFNDEF name Example :Similar to the example given for #ELSEIF. ''Note: All compiler preprocessor directives must start with the # sign. If you forget this, results will not be what you expect.''